import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import moment from 'moment';
import cn from 'classnames';
import { Tooltip, Icon, Empty, Modal, Button, message } from 'antd';
import { Link } from 'react-router-dom';
import copyImg from '@images/new_copy.svg';
import copyToClipboard from '@util/copy-to-clipboard';
import { List } from 'react-virtualized';
import { getDetailOnedayList } from '@api/task';

import { TASK_PRIORITY_MAP, TASK_PROTOCOL_MAP, TIME_UNIT_MAP } from '@util/constants';
import TargetCard from '@containers/task-manage/components/TargetCard';
import getRealTime from '@util/get-real-time';
import './index.less';
import { withRouter } from 'react-router';
import { connect } from 'react-redux';

const TaskInfo = props => {
  const { task, defaultInterface, history, nodeRole } = props,
    taskParams = _.get(task, 'onedayTaskParams', {}),
    taskTargets = [];
  const [visibleMoreModal, setVisibleMoreModal] = useState('');
  const [pagination, setPagination] = useState({ page: 1, pageSize: 100 });
  const [list, setList] = useState('');
  const OnedayList = (type = 'all') => {
    getDetailOnedayList({
      type: type,
      taskId: task._id,
      roundId: task.currentRoundOid,
      page: pagination.page,
      pageSize: pagination.pageSize
    }).then(r => {
      const { list } = r.data.data;
      setList(list);
    });
  };

  if (['custom', 'siteIdList', 'targetGroup'].includes(_.get(taskParams, 'target.queryType'))) {
    if (_.get(taskParams, 'target.showList.length')) {
      taskTargets.push(..._.get(taskParams, 'target.showList', []));
    }
  } else if (_.get(taskParams, 'target.count') !== 0) {
    taskTargets.push(_.get(taskParams, 'target.description'));
  }

  const clear = () => {
    setPagination({ page: 1, pageSize: 100 });
    setList([]);
  };
  useEffect(() => {
    if (task._id) {
      OnedayList('part');
    }
  }, [task, pagination.page, visibleMoreModal]);
  const timing = _.get(task, 'timing', {});
  let predictNextStartAt = '-';
  let lastStartTIme = '-';
  let detectionTime = '-';
  lastStartTIme = _.get(task, 'lastStart');
  const status = _.get(task, 'status');
  const pendingTime = _.get(task, 'pendingTime', '');
  const lastEnd = _.get(task, 'lastEnd');
  const recentEndTime =
    !['processing', 'paused', 'stopped'].includes(status) && _.get(task, 'lastEnd');
  // 最近一轮开始时间
  if (status === 'finished') {
    detectionTime = getRealTime(lastStartTIme, lastEnd, pendingTime, 'done');
  }
  if (_.get(task, 'isCycle')) {
    const lastEnd = _.get(task, 'lastEnd');
    const interval = _.get(task, 'intervalTime');
    const unit = `${_.get(task, 'intervalUnit')}`;
    const status = _.get(task, 'status');
    const endAt = _.get(timing, 'endAt');
    const dailyEnd = _.get(timing, 'dailyEnd');
    const dailyStart = _.get(timing, 'dailyStart');
    const intervalTime = moment(lastEnd)
      .add(interval, unit)
      .format('YYYY-MM-DD HH:mm:ss');
    const isBetween = (dailyStart, dailyEnd, intervalTime) => {
      let dailyStartDate = new Date(moment(intervalTime));
      dailyStartDate.setHours(dailyStart.split(':')[0]);
      dailyStartDate.setMinutes(dailyStart.split(':')[1]);
      let dailyEndDate = new Date(moment(intervalTime));
      dailyEndDate.setHours(dailyEnd.split(':')[0]);
      dailyEndDate.setMinutes(dailyEnd.split(':')[1]);
      if (
        moment(moment(intervalTime).format('YYYY-MM-DD HH:mm')).isBetween(
          moment(dailyStartDate).format('YYYY-MM-DD HH:mm'),
          moment(dailyEndDate).format('YYYY-MM-DD HH:mm')
        )
      ) {
        return true;
      }
      return false;
    };
    const InspectionTime = () => {
      if (endAt || dailyEnd) {
        if (intervalTime < moment(endAt).format('YYYY-MM-DD HH:mm:ss')) {
          if (dailyStart && dailyEnd) {
            return isBetween(dailyStart, dailyEnd, intervalTime);
          }
          return true;
        }
        if (dailyStart && dailyEnd) {
          return isBetween(dailyStart, dailyEnd, intervalTime);
        }
        return false;
      }
      return true;
    };
    // 预计下轮开始时间不能超出设置的任务执行时限
    if (
      lastEnd &&
      interval &&
      unit &&
      recentEndTime &&
      !['paused', 'stopped'].includes(status) &&
      InspectionTime()
    ) {
      predictNextStartAt = moment(lastEnd)
        .add(interval, unit)
        .format('YYYY-MM-DD HH:mm:ss');
    }
  }

  const interfaces = _.get(taskParams, 'interface', 'any');
  let connectionCount = _.get(taskParams, 'connectionCount');
  if (connectionCount === 0) {
    connectionCount = '不限制';
  }

  const timingStartAndEnd =
    _.get(timing, 'startAt') && _.get(timing, 'endAt')
      ? `${_.get(timing, 'startAt')} 至 ${_.get(timing, 'endAt')}`
      : _.get(timing, 'startAt')
      ? `任务须在${_.get(timing, 'startAt')}以后开始`
      : _.get(timing, 'endAt')
      ? `任务须在${_.get(timing, 'endAt')}以前结束`
      : '不限制';
  const details = [
    ['忽略网络打印机端口', _.get(taskParams, 'ignorePrinterPortCheck', false) ? '是' : '否'],
    [
      '禁扫目标',
      _.get(task, 'ignoreType', []).includes('whiteList') ? (
        <span>
          启用&nbsp;&nbsp;&nbsp;&nbsp;<Link to={'/asset-config/white-list'}>查看详情</Link>
        </span>
      ) : (
        '禁用'
      )
    ],
    ['Web指纹探测', _.get(taskParams, 'webFingerprintDetection', false) ? '是' : '否'],
    ['操作系统深度探测', _.get(taskParams, 'depthDetect', true) ? '是' : '否'],
    [
      '协议类型',
      _.get(taskParams, 'protocol', [])
        .map(protocol => TASK_PROTOCOL_MAP[protocol])
        .filter(Boolean)
        .join('、') || '-'
    ],
    ['国产化识别', '系统软件、数据库、操作系统、硬件设备'],
    ['最大连接并发数', `${connectionCount ? connectionCount : '-'}`],
    [
      '扫描带宽',
      _.get(taskParams, 'speedLimit') ? `${_.get(taskParams, 'speedLimit')}Kbps` : '无限制'
    ],
    [
      '任务类型',
      _.get(task, 'isCycle')
        ? `周期(${_.get(task, 'intervalTime')}${TIME_UNIT_MAP[_.get(task, 'intervalUnit')]})`
        : '单次'
    ],

    ['定时设置', timingStartAndEnd],
    [
      '每日允许时间段',
      _.get(timing, 'dailyStart') && _.get(timing, 'dailyEnd')
        ? `${_.get(timing, 'dailyStart')} 至 ${_.get(timing, 'dailyEnd')}`
        : '-'
    ],
    ['扫描网口', interfaces === defaultInterface ? '默认' : `${interfaces}`],
    ['优先级', TASK_PRIORITY_MAP[_.get(task, 'priority')] || '-'],
    [<div key="repeat">探测轮次</div>, `${_.get(task, 'times', 1) || 1}次`],
    ['最近一轮开始时间', lastStartTIme],
    ['最近一轮结束时间', recentEndTime || '-'],
    ['最近一轮检测耗时', detectionTime],
    ['预计下轮开始时间', predictNextStartAt]
  ].filter(Boolean);
  // eslint-disable-next-line react/prop-types
  if (nodeRole !== 'single') {
    details.splice(11, 1);
  }
  let targets = [],
    onedays = [];
  if (_.get(taskParams, 'target.description')) {
    targets.push(_.get(taskParams, 'target.description'));
  } else if (_.get(taskParams, 'target.sites.length')) {
    targets.push(
      ..._.map(_.get(taskParams, 'target.sites'), site =>
        [site.name, site.ip, site.url].filter(Boolean).join('|')
      )
    );
  }
  if (!targets.length) {
    targets.push('目标已被删除');
  }
  if (_.get(taskParams, 'oneday.showList.length') && _.get(taskParams, 'oneday.count', 0) !== 0) {
    onedays.push(..._.map(_.get(taskParams, 'oneday.showList')));
  } else if (_.get(taskParams, 'oneday.description')) {
    onedays.push(_.get(taskParams, 'oneday.description'));
  }
  // const modalDataMap = {
  //   targets: targets,
  //   onedays: onedays,
  //   usernames: _.get(taskParams, 'usernames', []),
  //   passwords: _.get(taskParams, 'passwords', [])
  // };

  const isCustom =
    _.get(taskParams, 'oneday.count') === -1 ||
    _.get(taskParams, 'oneday.queryType') === 'affectedByTarget';

  const titlesMap = {
    targets: `检测目标 (${_.get(taskParams, 'target.count', 0)})个`,
    onedays: isCustom ? '检测策略' : `检测策略 (${_.get(taskParams, 'oneday.count', 0)})个`
  };

  // eslint-disable-next-line
  const Targets = ({ type, items = [], width, className }) => {
    return (
      <div className={cn('ip-port-item', className)}>
        <div className="title">
          <span className="name">{titlesMap[type]}</span>
          {!isCustom && (
            <span className="show-more" onClick={() => setVisibleMoreModal(type)}>
              查看更多
            </span>
          )}
        </div>
        <div className="items">
          {items.map((item, index) => {
            return (
              <Tooltip key={index} title={item.name || item}>
                <div
                  className="item"
                  style={{ width }}
                  onClick={() => {
                    item.isModules
                      ? history.push({
                          pathname: '/asset-config/strategy-template',
                          query: { name: item.name }
                        })
                      : null;
                  }}
                >
                  {item.name || item}
                </div>
              </Tooltip>
            );
          })}
          {items.length === 0 && (
            <Empty style={{ width: '100%' }} image={Empty.PRESENTED_IMAGE_SIMPLE} />
          )}
        </div>
      </div>
    );
  };

  const moreModalFooter = [
    <Button
      type="primary"
      onClick={() => {
        setVisibleMoreModal('');
        clear();
      }}
      key="0"
    >
      关闭
    </Button>
  ];

  const titleModal = () => {
    const titleType = visibleMoreModal === 'targets' ? '检测目标' : '检测策略';
    return (
      <span>
        {titlesMap[visibleMoreModal]}
        <Tooltip title={titleType + '最多显示100个,您可通过复制按钮将全部检测策略名称复制出来'}>
          <Icon
            type="exclamation-circle"
            style={{ verticalAlign: 'text-bottom', marginLeft: '5px' }}
          />
        </Tooltip>
      </span>
    );
  };

  const Copy = () => {
    getDetailOnedayList({
      type: 'all',
      taskId: task._id,
      roundId: task.currentRoundOid
    }).then(r => {
      const { list } = r.data.data;
      setList(list);
      const res = copyToClipboard(list);
      res ? message.success('复制成功') : message.error('复制失败');
    });
  };

  const getOnedayList = () => {
    if (
      (_.get(taskParams, 'oneday.queryType') === 'list' ||
        _.get(taskParams, 'oneday.queryType') === 'template') &&
      _.get(taskParams, 'oneday.count', 0) !== 0
    ) {
      // 只需要返回前10条
      return _.get(taskParams, 'oneday.showList', []).slice(0, 10);
    } else if (_.get(taskParams, 'oneday.description') && isCustom) {
      return [
        {
          name: _.get(taskParams, 'oneday.description', ' '),
          isModules: false
        }
      ];
    } else {
      return [];
    }
  };

  return (
    <div className="task-info">
      <div className="task-name">
        <span className="name">{_.get(task, 'name', '-')}</span>
        <span className="type">漏洞普查任务</span>
      </div>
      <div className="task-info-detail">
        <div className="task-info-left">
          <TargetCard
            name={`探测目标 (${_.get(taskParams, 'target.count', '-')}) 个`}
            items={taskTargets}
            moreItems={taskTargets}
            type="target"
          />
          <TargetCard
            name={
              <div>
                {`探测端口 (${_.get(taskParams, 'portCount', '-')}) 个`}
                &nbsp;&nbsp;&nbsp;&nbsp;
                <Tooltip
                  title={
                    '如果该漏洞普查任务探测的目标是从资产管理列表勾选资产下发的任务，系统除了会探测用户自定义的端口，还会探测这些资产现有存活的端口和所勾选漏洞插件可能存在的默认端口。'
                  }
                >
                  <Icon type="exclamation-circle" style={{ marginTop: 4, marginLeft: -6 }} />
                </Tooltip>
              </div>
            }
            items={_.get(taskParams, 'ports', 0)}
            moreItems={_.get(taskParams, 'ports', 0)}
            type="port"
          />
          <Targets type="onedays" items={getOnedayList()} />
          {details.slice(0, 5).map((detail, index) => {
            return (
              <div className="detail-item" key={index}>
                <span className="name">{detail[0]}</span>
                <span className="value">{detail[1]}</span>
              </div>
            );
          })}
        </div>
        <div className="task-info-right">
          {details.slice(5).map((detail, index) => {
            return (
              <div className="detail-item" key={index}>
                <span className="name">{detail[0]}</span>
                <span className="value">{detail[1]}</span>
              </div>
            );
          })}
        </div>
      </div>
      <Modal
        maskClosable={false}
        visible={Boolean(visibleMoreModal)}
        title={titleModal()}
        onCancel={() => {
          setVisibleMoreModal('');
        }}
        className={cn('more-strategy', 'no-header-bottom-lines', 'bottom-center', 'padding-24')}
        footer={moreModalFooter}
      >
        <div className="items">
          {_.get(list, 'length') ? (
            <>
              <img src={copyImg} className={'copy-img'} onClick={Copy} />
              <List
                width={472}
                height={330}
                rowCount={list.length}
                rowRenderer={({ index, key, style }) => {
                  let item = _.get(list, `${index}`, '');
                  style.width = 'auto';
                  style.marginLeft = '50px';
                  style.paddingBottom = '8px';
                  return (
                    <Tooltip title={item.name || item} key={key}>
                      <div style={style}>
                        <div className="item">{item.name || item}</div>
                      </div>
                    </Tooltip>
                  );
                }}
                rowHeight={33}
                overscanRowCount={10}
              />
            </>
          ) : (
            <div className="empty">
              <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
            </div>
          )}
        </div>
      </Modal>
    </div>
  );
};

const mapStateToProps = state => {
  return {
    nodeRole: _.get(state, 'auth.cert.nodeRole', 'single')
  };
};

TaskInfo.propTypes = {
  task: PropTypes.object,
  defaultInterface: PropTypes.string,
  history: PropTypes.object,
  nodeRole: PropTypes.string
};

export default withRouter(connect(mapStateToProps)(TaskInfo));
